"""
@账号垫付相关逻辑
"""

import re
import logging
import uuid
import json
from flask import request, Blueprint, session, views
from flask_jwt_extended import jwt_required, get_jwt_identity
from base.tools.develop_tools import JsonResult, rand_num
from service.api import API
from service.personal_center.personal_api import UserAPI, PersonalApi
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from base.wx_pay.wx_pay import WXPAY

blueprint = Blueprint("advance_order_service", __name__, url_prefix="/advance_order/")
logger = logging.getLogger("advance_order_service")


class AdvanceOrderManager(views.MethodView):

    def __init__(self) -> None:
        self.api = AdvanceOrderAPI()

    @jwt_required()
    def get(self):
        try:
            user_id = get_jwt_identity()
            res = self.api.get_orders(user_id)
            return JsonResult.ok(f"获取成功!", data=res)
        except Exception as ex:
            logger.exception(f"获取订单失败!{str(ex)}")
            return JsonResult.error("获取订单失败!")

    @jwt_required()
    def post(self):
        try:
            request_args = request.get_json()
            game_name = request_args.get("game_name")
            game_zone = request_args.get("game_zone")
            game_cell = request_args.get("game_cell")
            account_qq = request_args.get("account_qq")
            account_phone = request_args.get("account_phone")
            account_price = request_args.get("account_price")
            pay_times = request_args.get("pay_times")
            first_fee = request_args.get("first_fee")
            per_month_fee = request_args.get("per_month_fee")
            start_time = request_args.get("start_time")
            rate = request_args.get("rate")
            owner_wx = request_args.get("owner_wx")
            owner_phone = request_args.get("owner_phone")
            order_desc = request_args.get("order_desc")
            belong = request_args.get("belong")
            operate_user = get_jwt_identity()
            if not UserAPI(user_id=operate_user).is_admin():
                return JsonResult.error("未管理员不能操作!")
            if not all(
                [
                    game_name,
                    game_zone,
                    game_cell,
                    account_qq,
                    account_phone,
                    account_price,
                    pay_times,
                    start_time,
                    owner_phone,
                    owner_wx,
                    rate,
                    belong
                ]
            ):
                return JsonResult.error("参数错误请检查!")
            account_price = int(account_price)
            pay_times = int(pay_times)
            if first_fee:
                first_fee = int(first_fee)
            if per_month_fee:
                per_month_fee = int(per_month_fee)
            self.api.create_order(
                operate_user=operate_user,
                game_name=game_name,
                game_zone=game_zone,
                game_cell=game_cell,
                account_qq=account_qq,
                account_phone=account_phone,
                account_price=account_price,
                pay_times=pay_times,
                rate=rate,
                first_fee=first_fee,
                per_month_fee=per_month_fee,
                start_time=start_time,
                owner_phone=owner_phone,
                owner_wx=owner_wx,
                order_desc=order_desc,
                belong=belong
            )
            return JsonResult.ok("创建订单成功")
        except Exception as e:
            logger.exception(f"操作失败!{str(e)}")
            return JsonResult.error("创建订单失败!")


class OrderPayInfo(views.MethodView):

    def __init__(self) -> None:
        self.api = AdvanceOrderAPI()

    @jwt_required()
    def get(self):
        try:
            user_id = get_jwt_identity()
            request_args = request.args
            main_order_id = request_args.get("main_order_id")
            sub_order_id = request_args.get("sub_order_id")
            price = request_args.get("price")
            if not all([main_order_id, sub_order_id, price]):
                return JsonResult.error(f"参数错误!")
            desc = "垫付支付订单"
            sub_order_id += f"_{rand_num(6)}"
            pay_info = WXPAY().get_pay_info(
                sub_order_id,
                desc,
                1,
                callback="http://35875af8.r22.cpolar.top/advance_order/callback",
                open_id=user_id,
                attach=main_order_id,
            )
            return JsonResult.ok("获取支付信息成功!", data=pay_info)
        except Exception as ex:
            logger.exception(f"获取支付信息失败!{str(ex)}")
            return JsonResult.error("获取支付信息失败!")


class OrderPayStatus(views.MethodView):

    def __init__(self) -> None:
        self.api = AdvanceOrderAPI()

    @jwt_required()
    def post(self):
        try:
            request_args = request.get_json()
            main_order_id = request_args.get("main_order_id")
            sub_order_id = request_args.get("sub_order_id")
            pay_status = request_args.get("pay_status", True)
            if not all([main_order_id, sub_order_id]):
                return JsonResult.error("参数错误!")
            operate_user = get_jwt_identity()
            if not UserAPI(user_id=operate_user).is_admin():
                return JsonResult.error("未管理员不能操作!")
            self.api.update_order_status(main_order_id, sub_order_id, pay_status)
            return JsonResult.ok("更新支付状态成功!")
        except Exception as ex:
            logger.exception(f"更新支付状态失败!{str(ex)}")
            return JsonResult.error("更新支付状态失败!")


class SMSCode(views.MethodView):

    def __init__(self) -> None:
        self.api = SmsAPI()

    @jwt_required()
    def get(self):
        try:
            request_args = request.args
            belong = request_args.get("belong")
            account_qq = request_args.get("account_qq")
            account_phone = request_args.get("account_phone")
            sms_code = self.api.get_sms_code(belong, account_phone, account_qq)
            if sms_code:
                return JsonResult.ok("获取验证码成功!", sms_code)
            else:
                return JsonResult.error("获取验证码失败!请稍后再试!")
        except Exception as ex:
            logger.exception(f"获取验证码失败!{str(ex)}")
            return JsonResult.error("获取验证码失败!")        

    def post(self):
        try:
            request_args = request.get_json()
            text = request_args.get("text")
            text = re.sub(r"[\x00-\x1F\x7F-\x9F]", "", text)
            info = json.loads(text)
            sms_from = info.get("from")
            sms = info.get("sms")
            card = info.get("card")
            ctime = info.get("receive_time")
            res = self.api.insert_sms(sms_from, sms, card, ctime)
            if res:
                return JsonResult.ok("插入验证码成功!")
            else:
                logger.info(f"插入验证码失败!无效验证码!")
                return JsonResult.ok("插入验证码失败!")
        except Exception as ex:
            logger.exception(f"插入验证码失败!{str(ex)}")
            return JsonResult.error("插入验证码失败!")


class AdvanceOrderAPI(API):
    def __init__(self) -> None:
        super().__init__()
        self.table_name = "advance_order"
        self.table = self._mongo[self.table_name]

    def create_order(
        self,
        operate_user,
        game_name,
        game_zone,
        game_cell,
        account_qq,
        account_phone,
        account_price,
        pay_times,
        rate,
        first_fee,
        per_month_fee,
        start_time,
        owner_phone,
        owner_wx,
        order_desc,
        belong
    ):
        order_id = f"DFMAIN-{str(uuid.uuid4())[:20].replace('-', '').upper()}"
        # 利息
        rate = int(rate) / 100
        rate_money = int(account_price * rate)
        service_monry = int(account_price * 0.03)
        if not per_month_fee:
            if not first_fee:
                per_month_fee = int((account_price - first_fee) / (pay_times))
            else:
                per_month_fee = int((account_price - first_fee + service_monry) / (pay_times))
        if not first_fee:
            if account_price >= 10000:
                first_fee = int(account_price * 0.2)
            else:
                first_fee = int(account_price * 0.3)

        start = datetime.strptime(start_time, "%Y-%m-%d")
        pay_list = [
            {
                "sub_order_id": f"DFFIRST-{str(uuid.uuid4())[:20].replace('-', '').upper()}",
                "yuan_jia": first_fee,
                "li_xi": rate_money,
                "pay_status": "待支付",
                "should_pay": first_fee + service_monry,
                "should_pay_date": start.strftime("%Y-%m-%d"),
            }
        ]
        for m in range(1, pay_times + 1):
            pay_list.append(
                {
                    "sub_order_id": f"DFSUB-{str(uuid.uuid4())[:20].replace('-', '').upper()}",
                    "yuan_jia": per_month_fee,
                    "li_xi": rate_money,
                    "should_pay": per_month_fee + rate_money,
                    "pay_status": "待支付",
                    "should_pay_date": (start + relativedelta(months=m)).strftime(
                        "%Y-%m-%d"
                    ),
                }
            )

        self.table.insert_one(
            {
                "operate_user": operate_user,
                "order_id": order_id,
                "game_name": game_name,
                "game_zone": game_zone,
                "game_cell": game_cell,
                "account_qq": account_qq,
                "account_phone": account_phone,
                "account_price": account_price,
                "pay_times": pay_times,
                "rate": rate,
                "owner_phone": owner_phone,
                "owner_wx": owner_wx,
                "pay_list": pay_list,
                "order_desc": order_desc,
                "pay_status": "待支付",
                "belong": belong,
                "ctime": datetime.now(),
            }
        )

    def get_orders(self, user_id):
        if UserAPI(user_id).is_admin():
            return list(self.table.find({}, {"_id": 0}))
        else:
            user_info = PersonalApi().get_user_info(user_id)
            return list(
                self.table.find({"owner_phone": user_info.get("phone_num")}, {"_id": 0})
            )

    def get_pay_list(self, main_order_id):
        order_info = self.table.find_one({"order_id": main_order_id}, {"_id": 0})
        return order_info.get("pay_list")

    def update_order_status(self, main_order_id, sub_order_id, pay_status):
        if pay_status:
            pay_status = "已支付"
        else:
            pay_status = "待支付"
        self.table.update_one(
            {"order_id": main_order_id, "pay_list.sub_order_id": sub_order_id},
            {"$set": {"pay_list.$.pay_status": pay_status}},
        )
        pay_list = self.get_pay_list(main_order_id)
        for pay in pay_list:
            if pay.get("pay_status") == "待支付":
                break
        else:
            self.table.update_one(
                {"order_id": main_order_id}, {"$set": {"pay_status": pay_status}}
            )


class SmsAPI(API):
    """
    腾讯QQ号模板:
    修改密码:
        【腾讯科技】你正在「修改QQ33*****80的密码」，验证码194592。
        提供给他人会导致QQ被盗和资产损失，若非本人操作，请修改密码。
    登录验证:
        【腾讯科技】你正在「登录QQ15******09」，验证码910776。
        提供给他人会导致QQ被盗和资产损失，若非本人操作，请修改密码。
    完美世界模板:
        【完美世界】验证码：515340，您正在登录完美世界游戏账号（3分钟内有效，如非本人操作，请忽略）
    """

    def __init__(self) -> None:
        super().__init__()
        self.table_name = "sms"
        self.table = self._mongo[self.table_name]

    def insert_sms(self, sms_from, sms, card, ctime):
        sms_type, action_type, sms_code, account_qq = self.match_sms(sms=sms)
        if not all([sms_type, action_type, sms_code]):
            return False
        self.table.insert_one(
            {
                "from": sms_from,
                "belong": sms_type,
                "action_type": action_type,
                "sms_code": sms_code,
                "card": card,
                "text": sms,
                "account_qq": account_qq,
                "ctime": ctime,
            }
        )
        return True

    def match_sms(self, sms):
        # 由于完美世界一个手机号只能绑定一个号,account_num只用做QQ号识别使用
        account_qq = None
        sms_type = None
        action_type = None
        sms_code = None

        if "【完美世界】" in sms:
            sms_type = "完美世界"
            sms_code = self.get_wanmei_code(sms=sms)
            if "您正在登录完美世界游戏账号" in sms:
                action_type = "login"
        elif "【腾讯科技】" in sms:
            sms_type = "腾讯科技"
            des = self.get_operation(sms)
            sms_code = self.get_tencent_code(sms=sms)
            if "QQ" in des and "登录" in des:
                action_type = "login"
                account_qq = des[4:]
        return sms_type, action_type, sms_code, account_qq

    def get_wanmei_code(self, sms):
        sms_code = None
        pattern = r"验证码：(\d+)"
        match = re.search(pattern, sms)
        if match:
            sms_code = match.group(1)
        return sms_code

    def get_tencent_code(self, sms):
        sms_code = None
        pattern = r"验证码(\d+)"
        match = re.search(pattern, sms)
        if match:
            sms_code = match.group(1)
        return sms_code

    def get_operation(self, sms):
        pattern = r"「(.*?)」"
        # 使用 re.search 方法查找匹配项
        match = re.search(pattern, sms)

        if match:
            # 提取匹配到的操作描述
            operation_description = match.group(1)
            return operation_description
        else:
            return None

    def get_sms_code(self, belong, account_phone, account_qq):
        ctime = datetime.now() - timedelta(minutes=5)
        if belong == "完美世界":
            res = self.table.find_one(
                {
                    "card": {"$regex": account_phone},
                    "belong": belong,
                    "ctime": {"$gt": ctime.strftime("%Y-%m-%d %H:%M:%S")},
                },
                sort=[("ctime", -1)],
            )
        else:
            res = self.table.find_one(
                {
                    "card": {"$regex": account_phone},
                    "account_qq": {"$regex": f"{account_qq[0]}.*{account_qq[-1]}"},
                    "belong": belong,
                    "ctime": {"$gt": ctime.strftime("%Y-%m-%d %H:%M:%S")},
                },
                sort=[("ctime", -1)],
            )
        return res.get("sms_code") if res else res


blueprint.add_url_rule("/advance_order", view_func=AdvanceOrderManager.as_view("advance_order_manager"))
blueprint.add_url_rule("/pay_info", view_func=OrderPayInfo.as_view("OrderPayInfo"))
blueprint.add_url_rule("/pay_status", view_func=OrderPayStatus.as_view("OrderPayStatus"))
blueprint.add_url_rule("/sms_code", view_func=SMSCode.as_view("SMSCode"))
